/* PROLOGUE */

%{
#include <stdio.h>
#include <string.h>
#include "semantics/semantics.h"

 /* bison functions */
void yyerror(const char* str);
int yywrap();

int hw2_parseError = 0;
 /* going globals crazy to match the style */
 /* extern pSomeLookupTable table; */


 /* complete (?) interface of global vars */
 /* extern FILE  *yyin, *yyout;
	extern char *yytext, *yyprevious, *yysptr, *yysbuf;
  */
	struct ArgumentTag;
	struct AnonymousStatementTag;
%}

/* DECLARATIONS AKA */
/* TERMINALS / TOKENS / <not this> ::= this */

%token COLON OPEN_PAREN CLOSE_PAREN
%token LABEL PARAMETER_VARIABLE STRING_LITERAL COMMENT RESERVED_WORD

%type <statement> anonymous_statement
%type <string> LABEL
%type <string> operation
%type <arg> argument
%type <args> arguments
%type <string> PARAMETER_VARIABLE
%type <string> STRING_LITERAL

 /* .number not used */
%union
{
	int number;
	char *string;
	struct ArgumentTag* arg;
	struct ArgumentTag** args;
	struct AnonymousStatementTag* statement;
}

%%

/* GRAMMAR RULES AKA */
/* NON - TERMINALS / <this> ::= <or this> not this */
program:
	COMMENT
	| labeled_statement
	| COMMENT program
	| labeled_statement program
	;

labeled_statement:
	LABEL COLON anonymous_statement
	{ labeledStatementFunction($1, $3); }
	;

anonymous_statement:
	OPEN_PAREN operation arguments CLOSE_PAREN
	{ $$ = anonymousStatementFunction($2, $3); }

	| OPEN_PAREN operation CLOSE_PAREN
	{ $$ = anonymousStatementFunction($2, NULL); }
	;

operation: LABEL | RESERVED_WORD
	;

 /* TODO: assign semantics to arguments */
arguments:
	argument
	{$$ = argumentsFunction(1, $1); }

	| argument argument
	{$$ = argumentsFunction(2, $1, $2); }

	| argument argument argument
	{$$ = argumentsFunction(3, $1, $2, $3); }

	| argument argument argument argument
	{$$ = argumentsFunction(4, $1, $2, $3, $4); }

	| argument argument argument argument argument
	{$$ = argumentsFunction(5, $1, $2, $3, $4, $5); }

	| argument argument argument argument argument argument
	{$$ = argumentsFunction(6, $1, $2, $3, $4, $5, $6); }

	| argument argument argument argument argument argument argument
	{$$ = argumentsFunction(7, $1, $2, $3, $4, $5, $6, $7); }

	| argument argument argument argument argument argument argument argument
	{$$ = argumentsFunction(8, $1, $2, $3, $4, $5, $6, $7, $8); }

	| argument argument argument argument argument
		argument argument argument argument
	{$$ = argumentsFunction(9, $1, $2, $3, $4, $5, $6, $7, $8, $9); }

	;

argument:
	anonymous_statement  { $$ = Argument_newFromAnonymousStatement($1); }
	| PARAMETER_VARIABLE { $$ = Argument_newFromCString($1); }
	| STRING_LITERAL     { $$ = Argument_newFromCString($1); }
	;

%%

 /* Bison functions */
void yyerror(const char *str)
{
	fprintf(stderr,"error: %s\n",str);
	hw2_parseError = 1;
}

int yywrap()
{
	return 1;
}
